package object;

import java.awt.Color;

import ray.Ray;
import scene.SceneObject;

import util.Point3D;
import util.Vector3D;

public class Sphere extends SceneObject {

	private float radius;
	private Point3D center;

	public Sphere(Point3D center, float radius, Color baseColor) {
		super(baseColor);
		this.center = center;
		this.radius = radius;
	}

	@Override
	public Point3D getClosestIntersectionPoint(Ray r) {
		Point3D temp = r.getOrigin().minus(this.center).multiplyByScalar(2.0f);
		float B = r.getDirectionVector().dotProduct(temp.getX(), temp.getY(),
				temp.getZ());
		temp = r.getOrigin().minus(this.center);
		float C = temp.dotProduct(temp.getX(), temp.getY(), temp.getZ())
				- (float) Math.pow(radius, 2.0f);

		float root = (float) Math.pow(B, 2.0f) - (4.0f * C);
		float t;
		if (root < 0) {
			return null;
		} else if (root == 0) {
			t = (B * -1.0f) / 2.0f;
		} else {
			float answer1 = ((B * -1.0f) + (float) Math.sqrt(root)) / 2.0f;
			float answer2 = ((B * -1.0f) - (float) Math.sqrt(root)) / 2.0f;
			if (answer1 < answer2) {
				if (answer1 >= 0) {
					t = answer1;
				} else {
					t = answer2;
				}
			} else {
				if (answer2 >= 0) {
					t = answer2;
				} else {
					t = answer1;
				}
			}
		}

		if (t > 0) {
			return new Point3D(r.getOrigin().getX()
					+ (r.getDirectionVector().getX() * t), r.getOrigin().getY()
					+ (r.getDirectionVector().getY() * t), r.getOrigin().getZ()
					+ (r.getDirectionVector().getZ() * t));
		} else {
			return null;
		}
	}

	@Override
	public Vector3D getNormalAtPoint(Point3D p) {
		return new Vector3D(p.getX() - this.center.getX(), p.getY()
				- this.center.getY(), p.getZ() - this.center.getZ());
	}

}
